package com.wang.vagus.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.env.PropertySourceLoader;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.util.ResourceUtils;

import java.io.IOException;
import java.util.List;

/**
 * 批量加载config和config/{profile}/下自定义的配置文件
 * @author Wang
 * @date 2019/10/19 14:48
 */
public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {

    private static final Logger logger = LoggerFactory.getLogger(MyEnvironmentPostProcessor.class);

    private final ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();

    private final List<PropertySourceLoader> propertySourceLoaders;

    public MyEnvironmentPostProcessor() {
        this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class, getClass().getClassLoader());
    }

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        String[] activeProfiles = environment.getActiveProfiles();

        for (String activeProfile : activeProfiles) {
            for (PropertySourceLoader loader : this.propertySourceLoaders) {
                for (String fileExtension : loader.getFileExtensions()) {
                    String location1 = ResourceUtils.CLASSPATH_URL_PREFIX + "config/*." + fileExtension;
                    String location2 = ResourceUtils.CLASSPATH_URL_PREFIX + "config/" + activeProfile + "/*." + fileExtension;
                    Resource[] resources1 = new Resource[0];
                    Resource[] resources2 = new Resource[0];
                    try {
                        resources1 = this.resourcePatternResolver.getResources(location1);

                    } catch (IOException e) {
                        e.printStackTrace();
                        logger.error("加载配置文件失败,因为{}", e.getMessage(), e);
                    }
                    try {
                        resources2 = this.resourcePatternResolver.getResources(location2);

                    } catch (IOException e) {
                        e.printStackTrace();
                        logger.error("加载配置文件失败,因为{}", e.getMessage(), e);
                    }
                    Resource[] resources = new Resource[resources1.length + resources2.length];
                    System.arraycopy(resources1, 0, resources, 0, resources1.length);
                    System.arraycopy(resources2, 0, resources, resources1.length, resources2.length);

                    try {
                        for (Resource resource : resources) {
                            List<PropertySource<?>> propertySources = loader.load(resource.getFilename(), resource);
                            if (propertySources != null && !propertySources.isEmpty()) {
                                propertySources.forEach(environment.getPropertySources()::addLast);
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        logger.error("加载配置文件失败,因为{}", e.getMessage(), e);
                    }
                }
            }
        }
    }
}
